<script setup>
/**
 * 用法：
 * <RegionPicker
 *   v-model="selectedRegion"            // [{code,name},{...},{...}]
 *   v-model:codes="selectedCodes"       // ['11','1101','110101'] (可选)
 *   :level="3"
 * />
 */
import { ref, watch, computed, onMounted } from 'vue'
import { onShow } from '@dcloudio/uni-app'
import { getRegionTree } from '@/api'

const props = defineProps({
  modelValue: { type: Array, default: () => [] }, // [{code,name}]
  level: { type: Number, default: 3 },
  placeholder: { type: String, default: '请选择省市区' },
  disabled: { type: Boolean, default: false },
  title: { type: String, default: '选择省市区' }
})
const emits = defineEmits(['update:modelValue','change','confirm','cancel'])

const show = ref(false)
const cascaderData = ref([])    // 直接使用 API 返回 [{label,value,children}]
const innerCodes = ref([])      // 绑定到 up-cascader
const innerRegions = ref([])    // [{code,name}]
const inited = ref(false)

/**
 * 根据 codes 数组逐级查找树中对应的 [{code,name}]
 * 自动根据 codes.length 决定查找层级
 * @param {Array} codes - 例如 ['11','1101','110101']
 * @param {Array} tree  - 地区树 [{label,value,children}]
 */
const resolveRegionsByCodes = (codes = [], tree = []) => {
  const result = []
  if (!Array.isArray(codes) || !codes.length) return result

  const list = codes.map(v => String(v))
  let nodes = tree

  for (const code of list) {
    if (!Array.isArray(nodes) || nodes.length === 0) break
    const node = nodes.find(n => String(n?.value) === code)
    if (!node) break
    result.push({ code: node.value, name: node.label })
    nodes = node.children || []
  }
    console.log(result, 'resolveRegionsByCodes')
  return result
}

/** 从 regions 提取 codes */
const pickCodes = (regions = []) => {
    return (regions || []).map(r => r.code).slice(0, props.level)
}
  

/** 统一写入（以 codes 为准） */
const setByCodes = (codesArr = []) => {
  const normalized = (codesArr || []).slice(0, props.level)
  innerCodes.value = normalized
  innerRegions.value = resolveRegionsByCodes(normalized, cascaderData.value)
  emits('update:modelValue', innerRegions.value)
  emits('change', { codes: normalized, regions: innerRegions.value })
}

/** 统一写入（以 regions 为准） */
const setByRegions = (regionsArr = []) => {
  const codesArr = pickCodes(regionsArr || [])
  setByCodes(codesArr)
}

/** 加载数据（无转换） */
const fetchData = async () => {
  const {data} = await getRegionTree()
  cascaderData.value = Array.isArray(data) ? data : (data || [])
}

/** 初始化：codes 优先，其次 modelValue */
const initOnce = async () => {
  await fetchData()
  if (props.codes?.length) {
    setByCodes(props.codes)
  } else if (props.modelValue?.length) {
    setByRegions(props.modelValue)
  } else {
    setByCodes([])
  }
  inited.value = true
}

/** 联动：内部 codes 变化 → 回写外部 */
watch(innerCodes, (newVal) => {
  if (!inited.value) return
  const regions = resolveRegionsByCodes(newVal, cascaderData.value)
  innerRegions.value = regions
  emits('update:modelValue', regions)
  emits('change', { codes: newVal, regions })
}, { deep: true })

/** 外部 modelValue 改变 → 覆盖内部 */
watch(() => props.modelValue, (val) => {
  if (!inited.value) return
  const nextCodes = pickCodes(val || [])
  if (JSON.stringify(nextCodes) !== JSON.stringify(innerCodes.value)) {
    setByCodes(nextCodes)
  }
}, { deep: true })

const displayText = computed(() =>
  innerRegions.value.length ? innerRegions.value.map(r => r.name).join(' ') : props.placeholder
)

const onConfirm = (data) => {
    const regionData = resolveRegionsByCodes(data, cascaderData.value)
    console.log(data, 'confirm', innerCodes.value, regionData)
  emits('confirm', {
    code: data || innerCodes.value,
    region: regionData
  })
}
const onCancel = () => emits('cancel')

onMounted(initOnce)
onShow(async () => { if (!inited.value) await initOnce() })
</script>

<template>
  <view class="region" @click="!disabled && (show = true)">
    <view
      class="region-box"
      :class="{ disabled }"
    >
      <!-- <up-icon name="map-fill"></up-icon> -->
      <view class="region-content">
        <text class="region-text">{{ displayText }}</text>
      </view>
      <!-- <up-icon name="arrow-right"></up-icon> -->
    </view>

    <up-cascader
      v-model:show="show"
      v-model="innerCodes"
      :data="cascaderData"
      :title="title"
      :level="level"
      @confirm="onConfirm"
      @cancel="onCancel"
    />
  </view>
</template>

<style scoped lang="scss">
.region {
  width: 100%;
  .region-box {
    width: 100%;
    display: flex;
    align-items: center;
    gap: 12rpx;
    line-height: 28rpx;
    &.disabled {
      opacity: 0.6;
    }
    .region-content {
      flex: 1;
      .region-text {
        font-size: 28rpx;
        color: #333;
      }
    }
  }
}
</style>
